package com.amigo.online.provider.video.mongo.dao.impl;

import java.util.List;

import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import com.amigo.online.provider.video.common.ConstantValue;
import com.amigo.online.provider.video.mongo.dao.VideoDao;
import com.amigo.online.provider.video.mongo.entity.VideoEntity;
import com.mongodb.BasicDBObject;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.result.UpdateResult;

@Component
public class VideoDaoImpl implements VideoDao {

    protected static final Logger logger = LoggerFactory.getLogger(VideoDaoImpl.class);

    @Autowired
    @Qualifier("readMongoTemplate")
    MongoTemplate readMongoTemplate;

    @Autowired
    @Qualifier("writeMongoTemplate")
    MongoTemplate writeMongoTemplate;

    @Override
    public void saveVideo(VideoEntity video) {
        writeMongoTemplate.save(video);
    }

    @Override
    public Long updateVideo(VideoEntity video) {
        Query query = new Query(Criteria.where("id").is(video.getId()));
        Update update = new Update().set("userId", video.getUserId())
                .set("cover", video.getCover())
                .set("type", video.getType())
                .set("recommended", video.getRecommended())
                .set("nickname", video.getNickname())
                .set("avatar", video.getAvatar())
                .set("createdTime", video.getCreatedTime())
                .set("loc", video.getLoc());
        UpdateResult result = writeMongoTemplate.updateFirst(query, update, VideoEntity.class);
        if (result != null) {
            return result.getModifiedCount();
        } else {
            return 0L;
        }
    }

    @Override
    public void deleteVideoById(Long id) {
        Query query = new Query(Criteria.where("id").is(id));
        writeMongoTemplate.remove(query, VideoEntity.class);
    }


    @Override
    public VideoEntity getVideoById(Long id) {
        Query query = new Query(Criteria.where("id").is(id).and("deleted").is(ConstantValue.VIDEO_UNDELETED_FLAG));
        return readMongoTemplate.findOne(query, VideoEntity.class);
    }

    @Override
    public AggregateIterable<Document> findAroundVideo(String collection, Double[] point, int searchMaxdistance,
                                                       BasicDBObject query, List<BasicDBObject> pipeline) {
        BasicDBObject aggregate = new BasicDBObject("$geoNear",
                new BasicDBObject("near",
                        new BasicDBObject("type", "Point").append("coordinates", point))
                        .append("distanceField", "distance")
                        .append("query", query)
                        .append("maxDistance", searchMaxdistance).append("spherical", true));
        pipeline.add(0, aggregate);
        AggregateIterable<Document> iterators = readMongoTemplate.getCollection(collection).aggregate(pipeline);
        return iterators;
    }

    @Override
    public void deleteVideoByIds(List<Long> ids) {
        Query query = new Query(Criteria.where("id").in(ids));
        writeMongoTemplate.remove(query, VideoEntity.class);

    }

}
